iT邦幫忙

DAY 15
2

emacs的30天學習筆記系列 第 27

emacs 做中學第二十六天:繼續gsoap client

  • 分享至 

  • xImage
  •  

想不到線上遊戲成癮的堂弟,竟然讓中華電信線路繼續斷線,alarm的紅燈一閃一閃的亮著,不禁有跌破眼鏡,看走眼的感覺,對他的看法,也改變不少。上癮仍可以戒掉的,不知道他習慣十數小時摸著鍵盤滑鼠的手,會不會顫抖?

原來想用gsoap2是因為Aubit 4gl(http://aubit.com/) 公司開源的GNU 4GL相容的編譯器方案,裏有一個範例,是4gl 通過gsoap2 連結別人的web service。所以興起了一個念頭,就是大量reuse 現存的4gl 源碼,把一些常用的查詢(報表)soap web service化。其實專案的重點是soap 的server端,而不是client端,可以連結別人的web service,只是附屬的,主要是輸出(匯出 自己的web service)。凡事總有例外,支線反客為主變成主線,回到一週前,在那個轉折點,真不該鑽入這個小牛角尖。

IT 這個行業,或所謂的專案管理,總是有exception 意外,有but,想起老搖滾團,
meat loaf一首歌劇搖滾,I would do anything for you,I would do anything for love, But I wont do that.

昨天講到史托曼先生的犬儒,憤世,把用Apple產品的人比喻成失去自由的傻瓜。很難想像這樣的人發起自由軟體運動,領導著全球志願者追求軟體自由,一路走來始終如一,30年後脾氣仍然火爆。
專案有這種人,怎麼結案呢?BUT**,BUT,BUT**這種人推動著地球上活躍的專案。

最近,芒果機出來了,或是未來的WIN 8, WIN9, 有些人能夠付費當首批白老鼠,所謂的key customer已經倍感榮幸,feedback 改進經驗給 軟體公司感動的快哭出來。就是有些人覺得這樣不夠,遠遠不夠,回饋的不只是操作等級或二進位等級,一定要是源碼 source code等級,這樣才有參與感。也許是一種參與,平起平坐,才讓星星之火,不滅,風來了又旺旺的燒著。
有時候,給你源碼,仍不會用。真慘。

#include "soapH.h"
#include "BasicHttpBinding_USCOREICurrencyService.nsmap"


int main(int argc, char **argv)
{ 
	struct soap soap;
	enum ns5__CurrencyCode CurrCodeFrm;
	enum ns5__CurrencyCode CurrCodeTo;
	
	CurrCodeFrm =  ns5__CurrencyCode__TWD;
	CurrCodeTo =  ns5__CurrencyCode__USD;
	
	struct _ns1__GetConversionRate GetRate;
	
	GetRate.FromCurrency = &CurrCodeFrm;
	
	GetRate.ToCurrency = &CurrCodeTo;
	
	struct _ns1__GetConversionRateResponse GetRes;
	
	struct ns5__Currency ns5_curr;
	
	GetRes.GetConversionRateResult = &ns5_curr;
	
	enum ns5__CurrencyCode resFromCurr;	/* *FromCurrency optional element of type ns5:CurrencyCode */
	enum ns5__CurrencyCode resToCurr;	/* optional element of type ns5:CurrencyCode */
	double  rate;	/* optional element of type xsd:double */

	ns5_curr.FromCurrency = &resFromCurr;
	
	ns5_curr.ToCurrency = &resToCurr;
	
	ns5_curr.Rate = &rate;

	soap_call___ns1__GetConversionRate(&soap , NULL , NULL , &GetRate ,&GetRes);
	
  if (soap.error)
  { soap_print_fault(&soap, stderr);
    exit(1);
  }
  else
    printf("result  Success!!");
  soap_destroy(&soap);
  soap_end(&soap);
  soap_done(&soap);
  return 0;
}

如果你翻譯後,執行,會出現下面畫面。

所以是不可以run 的code,請勿使用。

其中發生了一個小轉折,就是在我的mingw裏一直編譯不過。

挫折的想逃避。

後來 發現,
$ gcc -o calcclient calcclient.c soapClient.c soapC.c -lgsoap -lws2_32

這樣可以過。而這段指令是從
make的訊息裏,找到線索。

gcc -DMINGW -g -O2   -o calcclient.exe calcclient.o  soapClient.o soapC.o ../../../gsoap/libgsoap.a -lws2_32 -lkernel32 -luser32 -lgdi32

用消去法,把用不到的消掉,變成可以編譯的指令。

google ws2_32仍不知道,直接相關的原因,只有ws2_32的名詞解釋。

不加**-lws2_32**,一直給你秀 undefined refererence一秀一大堆,明明把
stdsoap2.c 一起編譯。

在gdb 的模式下,是經典的
Segmentation fault.

原來linux的**Segmentation fault.**就是winxp的那個畫面。
winxp 可以除錯,gdb 也可以除錯。

22              soap_call___ns1__GetConversionRate(&soap , NULL , NULL , &GetRat
e ,&GetRes);
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()

上面是在 main裏掛掉。準備往裏一層(step,step into)

(gdb) s
soap_call___ns1__GetConversionRate (soap=0x212898, soap_endpoint=0x0,
    soap_action=0x0, ns1__GetConversionRate=0x212888,
    ns1__GetConversionRateResponse=0x212884) at soapClient.c:25
25              if (!soap_endpoint)
(gdb) n
26                      soap_endpoint = "http://www.restfulwebservices.net/wcf/C
urrencyService.svc";
(gdb) n
27              if (!soap_action)
(gdb) n
28                      soap_action = "GetConversionRate";
----------------------------------------------------------
中間省略
-------------------------------------------------------
(gdb) n
47              if (soap_connect(soap, soap_endpoint, soap_action)

在soapClient.c的soap_connect掛掉。

再往下一層

soap_connect (soap=0x212898,
    endpoint=0x428260 "http://www.restfulwebservices.net/wcf/CurrencyService.svc
", action=0x42829a "GetConversionRate") at stdsoap2.c:15072
15072   { return soap_connect_command(soap, SOAP_POST, endpoint, action);
(gdb) s
soap_connect_command (soap=0x212898, http_command=2000,
    endpoints=0x428260 "http://www.restfulwebservices.net/wcf/CurrencyService.sv
c", action=0x42829a "GetConversionRate") at stdsoap2.c:15084
15084     if (endpoints && (s = strchr(endpoints, ' ')))
(gdb) n
15104       soap_try_connect_command(soap, http_command, endpoints, action);
(gdb) s
soap_try_connect_command (soap=0x212898, http_command=2000,
    endpoint=0x428260 "http://www.restfulwebservices.net/wcf/CurrencyService.svc
", action=0x42829a "GetConversionRate") at stdsoap2.c:15116
15116     soap->error = SOAP_OK;
(gdb) n
15117     strcpy(host, soap->host); /* save previous host name: if != then recon
nect */
(gdb) p host
----------------------------------------------------------
中間省略
-------------------------------------------------------
15158     if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC
_XML) && endpoint)
(gdb) n
15160       soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
(gdb) n
15161       if ((k & SOAP_IO) != SOAP_IO_FLUSH)
(gdb) n
15162         soap->mode |= SOAP_IO_BUFFER;
(gdb) n
15163       if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->por
t, soap->path, action, count)))
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()

連試了幾次,step ,沒法step into 進去。

小結:整個soap ,gsoap2 交換資料的核心動作,在trace過程中,知道在stdsoap2.c,而這個檔也包在函式庫 libgsoap.a裏,

這個檔,不是gsoap2的工具產生的,所以預設不放在自己的工作目錄裏。
用**-l**的方式引入,不用打路徑。
另外,endpoint,是提供服務的網址,而action是有在wsdl裏的定義的動作。
常常出現。

目前市面上,主流的web service有三種型式,除了soap,還有 xml rpc,及比較年輕的restful,後來出現的,比之前的定義簡單。所以會了困難的,要入門其他的,比較簡單。

soap,在核心檔stdsoap2.c,可以看得出來,主要還是network 程式的撰寫。
大量引用網路的系統呼叫。這程式很大,除錯訊息裏出現的行數,已經15163行。

之後2~3個晚上,再複習一下C語言的指標/結構用法,並向大師致敬。

以上是一個疑似bug的訊息??


上一篇
emacs 做中學第二十五天:未做完的gsoap client消費別人的web service
下一篇
懷舊C語言:1988年出版 The C Programming Language 2nd Edition
系列文
emacs的30天學習筆記38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言